package com.easysoft.commons.utils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

/**
 * DateTime 日期时间函数类
 * 
 * @author try
 * @version 1.0
 */
public final class DateTimeUtils {

	private static final String LOCAL_DATETIME_FORMAT = "yyyy-MM-dd HH:mm:ss";

	private DateTimeUtils() {
	}

	/**
	 * 获取系统当前日期/时间，精确到秒。
	 * 
	 * @return String 系统当前日期/时间
	 */
	public static Date getCurrentDate() {
		return new Date();
	}

	/**
	 * 获取系统当前日期/时间。
	 * 
	 * @param pattern
	 *            日期-时间字符串的格式。例如：yyyy-MM-dd HH:mm:ss
	 * @return Date 系统当前日期/时间
	 * @throws ParseException
	 */
	public static Date getCurrentDate(final String pattern) {
		if (pattern == null)
			return new Date();
		SimpleDateFormat dateFormat = new SimpleDateFormat(pattern);
		String strDate = dateFormat.format(new Date());
		try {
			return dateFormat.parse(strDate);
		}
		catch (ParseException e) {
			e.printStackTrace();
		}

		return null;
	}

	/**
	 * 获取系统标准格式的当前日期/时间字符串
	 * 
	 * @return String 日期/时间字符串
	 */
	public static String getCurrentLocal() {
		SimpleDateFormat dateFormat = new SimpleDateFormat(LOCAL_DATETIME_FORMAT);
		return dateFormat.format(new Date());
	}

	/**
	 * 获取系统标准格式的当前日期/时间字符串
	 * 
	 * @param pattern
	 *            日期-时间字符串的格式。例如：yyyy-MM-dd HH:mm:ss
	 * @return String 日期/时间字符串
	 */
	public static String getCurrentLocal(final String pattern) {
		if (pattern == null)
			return "";
		SimpleDateFormat dateFormat = new SimpleDateFormat(pattern);
		return dateFormat.format(new Date());
	}

	/**
	 * 获取系统当前日期所属季度
	 * 
	 * @return
	 */
	public static int getCurrentQuarterOfYear() {
		return DateTimeUtils.getQuarterOfYear(new Date());
	}

	/**
	 * 获取系统当前日期所属周
	 * 
	 * @return 系统当前时间所属周
	 */
	public static int getCurrentWeekOfYear() {
		return DateTimeUtils.getWeekOfYear(new Date());
	}

	/**
	 * 计算某天(基准日期)所处季度
	 * 
	 * @param date
	 *            基准日期
	 * @return int
	 */
	public static int getQuarterOfYear(Date date) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		int currentMonth = cal.get(Calendar.MONTH) + 1;

		if (currentMonth >= 1 && currentMonth <= 3) {
			return 1;
		}
		else if (currentMonth >= 4 && currentMonth <= 6) {
			return 2;
		}
		else if (currentMonth >= 7 && currentMonth <= 9) {
			return 3;
		}
		// else if (currentMonth >= 10 && currentMonth <= 12) {
		return 4;
		// }
	}

	/**
	 * 计算某天(基准日期)所处周
	 * 
	 * @param date
	 *            基准日期
	 * @return int
	 */
	public static int getWeekOfYear(final Date date) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		return cal.get(Calendar.WEEK_OF_YEAR);
	}

	/**
	 * 将给定的日期/时间字符串转换为 Date。
	 * 
	 * @param strDate
	 *            日期-时间字符串，必须满足“yyyy-MM-dd HH:mm:ss”格式。
	 * @return Date
	 */
	public static Date formatLocalToDate(final String strDate) {
		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		try {
			return dateFormat.parse(strDate);
		}
		catch (ParseException e) {
			e.printStackTrace();
		}

		return null;
	}

	/**
	 * 将给定的日期/时间字符串转换为 Date。
	 * 
	 * @param strDate
	 *            日期-时间字符串。
	 * @param pattern
	 *            日期-时间字符串的格式。例如：yyyy-MM-dd HH:mm:ss
	 * @return Date
	 */
	public static Date formatStringToDate(final String strDate, final String pattern) {
		SimpleDateFormat dateFormat = new SimpleDateFormat(pattern);

		try {
			return dateFormat.parse(strDate);
		}
		catch (ParseException e) {
		}

		return null;
	}

	/**
	 * 将给定的 Date 格式化为日期/时间字符串。
	 * 
	 * @param date
	 *            要被格式化的日期-时间值。
	 * @return 格式化的日期-时间字符串。
	 */
	public static String formatDateToLocal(final Date date) {
		if (date == null)
			return "";
		SimpleDateFormat dateFormat = new SimpleDateFormat(LOCAL_DATETIME_FORMAT);
		return dateFormat.format(date);
	}

	/**
	 * 将给定的 Date 格式化为日期/时间字符串。
	 * 
	 * @param date
	 *            要被格式化的日期-时间值。
	 * @param pattern
	 *            日期格式符号。
	 * @return 格式化的日期-时间字符串。
	 */
	public static String formatDateToString(final Date date, final String pattern) {
		if (date == null || pattern == null)
			return "";
		SimpleDateFormat dateFormat = new SimpleDateFormat(pattern);
		return dateFormat.format(date);
	}

	/**
	 * 根据日历的规则，为给定的日期字段添加或减去指定的时间量。 例如，要从当前日历时间减去 5 天，可以通过调用以下方法做到这一点： <br>
	 * add(date, Calendar.DAY_OF_MONTH, -5)。
	 * 
	 * @param date
	 *            基准日期
	 * @param field
	 *            日历字段。
	 * @param amount
	 *            为字段添加的日期或时间量。
	 * @return 计算后的新日期
	 */
	public static Date getDateAddAmount(final Date date, final int field, final int amount) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		cal.add(field, amount);
		return cal.getTime();
	}

	/**
	 * 计算某天(基准日期)开始时间<br>
	 * DateUtil.getDayFirstTime(new Date())
	 * 
	 * @param date
	 *            基准日期
	 * @return Date
	 */
	public static Date getDayFirstTime(final Date date) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		cal.set(Calendar.HOUR_OF_DAY, 0);
		cal.set(Calendar.MINUTE, 0);
		cal.set(Calendar.SECOND, 0);

		return cal.getTime();
	}

	/**
	 * 计算某天(基准日期)的结束时间<br>
	 * DateUtil.getDayLastTime(new Date())
	 * 
	 * @param date
	 *            基准日期
	 * @return Date
	 */
	public static Date getDayLastTime(final Date date) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		cal.set(Calendar.HOUR_OF_DAY, 23);
		cal.set(Calendar.MINUTE, 59);
		cal.set(Calendar.SECOND, 59);

		return cal.getTime();
	}

	/**
	 * 计算某天(基准日期)所处年度的开始日期<br>
	 * DateUtil.getYearFirstDay(new Date())
	 * 
	 * @param date
	 *            基准日期
	 * @return Date
	 */
	public static Date getYearFirstDay(final Date date) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		cal.set(Calendar.MONTH, Calendar.JANUARY); // 一月
		cal.set(Calendar.DATE, 1);
		cal.set(Calendar.HOUR_OF_DAY, 0);
		cal.set(Calendar.MINUTE, 0);
		cal.set(Calendar.SECOND, 0);

		return cal.getTime();
	}

	/**
	 * 计算某天(基准日期)所处季度的开始日期<br>
	 * DateUtil.getQuarterFirstDay(new Date())
	 * 
	 * @param date
	 *            基准日期
	 * @return Date
	 */
	public static Date getQuarterFirstDay(final Date date) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		int month = cal.get(Calendar.MONTH);
		if (month < Calendar.APRIL) {
			cal.set(Calendar.MONTH, Calendar.JANUARY); // 一月
		}
		else if (month < Calendar.JULY) {
			cal.set(Calendar.MONTH, Calendar.APRIL); // 四月
		}
		else if (month < Calendar.OCTOBER) {
			cal.set(Calendar.MONTH, Calendar.JULY); // 七月
		}
		else {
			cal.set(Calendar.MONTH, Calendar.OCTOBER); // 十月
		}
		cal.set(Calendar.DATE, 1);
		cal.set(Calendar.HOUR_OF_DAY, 0);
		cal.set(Calendar.MINUTE, 0);
		cal.set(Calendar.SECOND, 0);

		return cal.getTime();
	}

	/**
	 * 计算某天(基准日期)所处季度的结束日期<br>
	 * DateUtil.getQuarterLastDay(new Date())
	 * 
	 * @param date
	 *            基准日期
	 * @return Date
	 */
	public static Date getQuarterLastDay(final Date date) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		int month = cal.get(Calendar.MONTH);
		if (month <= Calendar.MARCH) {
			cal.set(Calendar.MONTH, Calendar.MARCH); // 三月
		}
		else if (month <= Calendar.JUNE) {
			cal.set(Calendar.MONTH, Calendar.JUNE); // 六月
		}
		else if (month <= Calendar.SEPTEMBER) {
			cal.set(Calendar.MONTH, Calendar.SEPTEMBER); // 九月
		}
		else {
			cal.set(Calendar.MONTH, Calendar.DECEMBER); // 十二月
		}

		cal.set(Calendar.DATE, cal.getActualMaximum(Calendar.DATE));
		cal.set(Calendar.HOUR_OF_DAY, 23);
		cal.set(Calendar.MINUTE, 59);
		cal.set(Calendar.SECOND, 59);

		return cal.getTime();
	}

	/**
	 * 计算某天(基准日期)所处月份的开始日期<br>
	 * DateUtil.getMonthFirstDay(new Date())
	 * 
	 * @param date
	 *            基准日期
	 * @return Date
	 */
	public static Date getMonthFirstDay(final Date date) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		cal.set(Calendar.DATE, 1);
		cal.set(Calendar.HOUR_OF_DAY, 0);
		cal.set(Calendar.MINUTE, 0);
		cal.set(Calendar.SECOND, 0);

		return cal.getTime();
	}

	/**
	 * 计算某天(基准日期)所处月份的结束日期<br>
	 * DateUtil.getMonthFirstDay(new Date())
	 * 
	 * @param date
	 *            基准日期
	 * @return Date
	 */
	public static Date getMonthLastDay(final Date date) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		cal.set(Calendar.DATE, cal.getActualMaximum(Calendar.DATE));
		cal.set(Calendar.HOUR_OF_DAY, 23);
		cal.set(Calendar.MINUTE, 59);
		cal.set(Calendar.SECOND, 59);

		return cal.getTime();
	}

	/**
	 * 计算某天(基准日期)所处周的开始日期<br>
	 * DateUtil.getWeekFirstDay(new Date())
	 * 
	 * @param date
	 *            基准日期
	 * @return Date
	 */
	public static Date getWeekFirstDay(final Date date) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		int weekNum = cal.get(Calendar.WEEK_OF_YEAR);
		cal.set(Calendar.WEEK_OF_YEAR, weekNum);
		cal.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
		cal.set(Calendar.HOUR_OF_DAY, 0);
		cal.set(Calendar.MINUTE, 0);
		cal.set(Calendar.SECOND, 0);

		return cal.getTime();
	}

	/**
	 * 计算某天(基准日期)所处周的结束日期<br>
	 * DateUtil.getWeekLastDay(new Date())
	 * 
	 * @param date
	 *            基准日期
	 * @return Date
	 */
	public static Date getWeekLastDay(final Date date) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		int weekNum = cal.get(Calendar.WEEK_OF_YEAR);
		cal.set(Calendar.WEEK_OF_YEAR, weekNum);
		cal.set(Calendar.DAY_OF_WEEK, Calendar.SATURDAY);
		cal.set(Calendar.HOUR_OF_DAY, 23);
		cal.set(Calendar.MINUTE, 59);
		cal.set(Calendar.SECOND, 59);

		return cal.getTime();
	}

	/**
	 * 计算某年某周的开始日期<br>
	 * DateUtil.getYearWeekFirstDay(2009, 39)
	 * 
	 * @param yearNum
	 *            某年
	 * @param weekNum
	 *            某周
	 * @return 某年某周的开始日期
	 */
	public static Date getYearWeekFirstDay(final int yearNum, final int weekNum) {
		Calendar cal = Calendar.getInstance();
		cal.set(Calendar.YEAR, yearNum);
		cal.set(Calendar.WEEK_OF_YEAR, weekNum);
		cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
		cal.set(Calendar.HOUR_OF_DAY, 0);
		cal.set(Calendar.MINUTE, 0);
		cal.set(Calendar.SECOND, 0);

		return cal.getTime();
	}

	/**
	 * 根据毫秒数创建对于的日期<br>
	 * DateUtil.formatMillis(10000000)
	 * 
	 * @param millis
	 *            基准日期毫秒数
	 * @return String 日期/时间字符串
	 */
	public static String formatMillis(long millis) {
		SimpleDateFormat dateFormat = new SimpleDateFormat(LOCAL_DATETIME_FORMAT);
		return dateFormat.format(new Date(millis));
	}

	/**
	 * 计算耗时<br>
	 * 
	 * @param startTime
	 *            开始时间
	 * @param endTime
	 *            结束时间
	 * @return long 耗时（秒）
	 */
	public static long subtractor(Date startTime, Date endTime) {

		if (startTime == null || endTime == null) {
			return 0L;
		}

		long startT = startTime.getTime();
		long endT = endTime.getTime();

		return (endT - startT) / (1000); // 共计秒数
	}

	/**
	 * 比较日期早晚，如果time1在time2之前，返回true，否则返回false<br>
	 * 
	 * @param time1
	 * @param time2
	 * @return boolean
	 */
	public static boolean before(Date time1, Date time2) {
		boolean isBefore = true;
		try {
			isBefore = time1.before(time2);
		}
		catch (Exception e) {
			e.printStackTrace();
		}
		return isBefore;
	}

	/**
	 * 判断时间是否在给定的范围内
	 * 
	 * @param date
	 *            需要判断的时间
	 * @param interval
	 *            时间范围
	 * @return ture：是；false：否
	 */
	public static boolean isBetween(final Date date, String between) {
		String[] times = between.split("-");
		long timeStart = Long.valueOf(times[0].replaceAll("[^x00-xff]*", "").replaceAll("[-\\s:]", ""));
		long timeEnd = Long.valueOf(times[1].replaceAll("[-\\s:]", ""));

		SimpleDateFormat format = new SimpleDateFormat("HH:mm");
		String currentTime = format.format(date);
		long currentTimel = Long.valueOf(currentTime.replaceAll("[-\\s:]", ""));

		if (currentTimel >= timeStart && currentTimel <= timeEnd) {
			return true;
		}
		else {
			return false;
		}
	}
	
	/**
	 * 判断是否在给区间时间内
	 * 
	 * @param interval
	 *            格式"8:30-20:00"
	 * @return boobean
	 */
	public static boolean isInterval(String timeStr) {
		String[] times = timeStr.split("-");
		long timeStart = Long.valueOf(times[0].replaceAll("[^x00-xff]*", "").replaceAll("[-\\s:]", ""));
		long timeEnd = Long.valueOf(times[1].replaceAll("[-\\s:]", ""));
		Date date = new Date();
		SimpleDateFormat format = new SimpleDateFormat("HH:mm");
		String currentTime = format.format(date);
		long currentTimel = Long.valueOf(currentTime.replaceAll("[-\\s:]", ""));

		if (currentTimel >= timeStart && currentTimel <= timeEnd) {
			return true;
		}
		else {
			return false;
		}
	}

	public static void main(String args[]) throws Exception {
		// 历史时间
		Date generateTime = formatLocalToDate("2015-08-31 12:12:12");
		System.out.println(formatDateToLocal(generateTime));

		// 基准时间
		Date baseTime = getDateAddAmount(generateTime, Calendar.HOUR_OF_DAY, 48);
		System.out.println(formatDateToLocal(baseTime));

		// 当前时间
		Date currentTime = getCurrentDate();
		System.out.println(formatDateToLocal(currentTime));

		// 如果baseTime的时间在currentTime之后（不包括等于）返回true
		System.out.println(baseTime.after(currentTime));

		// 计算 耗时
		/* System.out.println(countConsumeTime(null,new Date())); */
		System.out.println("***********" + before(new Date(), getDateAddAmount(new Date(), Calendar.HOUR_OF_DAY, 1)));
		System.out.println(new Date());
		System.out.println(getDateAddAmount(new Date(), Calendar.HOUR_OF_DAY, 25));
	}

}